from typing import Annotated,Literal

import uvicorn
from fastapi import FastAPI, Path, Query, Body
from fastapi.openapi.docs import get_swagger_ui_html, get_swagger_ui_oauth2_redirect_html, get_redoc_html
from starlette.staticfiles import StaticFiles
from pydantic import BaseModel, Field

# 创建FastAPI实例，禁用掉FastAPI会自动生成Swagger UI和Redoc文档
app = FastAPI(docs_url=None, redoc_url=None)

# 静态文件挂载（路由与静态文件映射）
app.mount("/static", StaticFiles(directory="../statics"), name="static")


# 重新提供一个Swagger UI，相当于我们自己重写了这么一个路由
@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )
@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
async def swagger_ui_redirect():
    return get_swagger_ui_oauth2_redirect_html()

# 这里与Swagger UI一样，重新提供Redoc
@app.get("/redoc", include_in_schema=False)
def custom_redoc():
    return get_redoc_html(
        openapi_url = "/openapi.json",
        title = "Redoc for FastAPI",
        redoc_js_url="/static/redoc.standalone.js"
    )

class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None

class Order(BaseModel):
    order_no: str
    receive_name: str


@app.post("/order/items")
async def create_item(item: Annotated[Item, Body(embed=True)]):
    return item


@app.post("/order")
async def create_order(item: Item, order: Order):
    order_dict = order.model_dump()
    result = {"order": order_dict}
    order_dict.update({"item": item.model_dump()})
    return result

@app.put("/order")
async def update_order(item: Item, order: Order, count: Annotated[int, Body(ge=10,le=1000)]):
    order_dict = order.model_dump()
    result = {"order": order_dict}
    order_dict.update({"item": item.model_dump()})
    return result | {'count': count}


@app.put("/order/{order_id}")
async def update_order(
        *,
        order_id: int,
        order:Order,
        item: Item,
        q: Annotated[str | None, Query()] =  None,
        count: Annotated[int, Body(ge=10,le=1000)]
):
    order_dict = order.model_dump()
    result = {"order": order_dict}
    order_dict.update({"order_id":order_id})
    item_dict = item.model_dump()
    order_dict.update({"item": item_dict})
    item_dict.update({'count': count})
    return result


@app.put("/items/{item_id}")
async def update_item(
        item_id: int,
        q: str | None = None,
        # 这里把请求体默认参数设置为None，它变为一个可选参数
        item: Item | None = None
):
    result = {
        "item_id": item_id
    }
    if q:
        result.update({"q": q})
    if item:
        result.update({"item": item})
    return result



if __name__ == '__main__':
    app.debug = True
    uvicorn.run("main:app", host="127.0.0.1", port=8007, reload=True)

